package agent.client.android.behaviours;

import jade.content.lang.Codec.CodecException;
import jade.content.lang.sl.SLCodec;
import jade.content.onto.OntologyException;
import jade.content.onto.basic.Action;
import jade.core.AID;
import jade.core.ContainerID;
import jade.core.behaviours.Behaviour;
import jade.domain.AMSService;
import jade.domain.FIPAException;
import jade.domain.FIPANames;
import jade.domain.FIPAAgentManagement.AMSAgentDescription;
import jade.domain.JADEAgentManagement.CreateAgent;
import jade.domain.JADEAgentManagement.JADEManagementOntology;
import jade.domain.JADEAgentManagement.KillAgent;
import jade.lang.acl.ACLMessage;
import jade.lang.acl.MessageTemplate;
import jade.util.Logger;
import agent.client.android.MainActivity;
import agent.client.android.utils.GetAID;
import android.util.Log;

/**
 * Behaviour che controlla se l'utente � gi� registrato
 * altrimenti aggiunge i bheaviours di richiesta registrazione
 * e di avvio agente sul server
 */
public class RegistrationControlBehaviour extends Behaviour {

	private static final long serialVersionUID = 1L;

	private MessageTemplate messageTemplate;

	private String password;
	private int step = 0;

	private AMSAgentDescription[] descriptions = null;

	private MainActivity activity;
	private Logger logger = Logger.getMyLogger(this.getClass().getName());

	String tag = "RegistrControlBehaviour";

	/*
	 * constructor
	 */

	public RegistrationControlBehaviour(MainActivity activity) {
		super();
		this.activity = activity;
	}

	@Override
	public void action() {

		switch (step) {
		case 0:
		{
			Log.i(tag, "step = 0");

			String nomeAgente = myAgent.getLocalName().replace("$mobile", "");

			AMSAgentDescription amsAgentDescription = new AMSAgentDescription();
			amsAgentDescription.setName(GetAID.aid(nomeAgente));

			logger.info("NOME AGENTE" + nomeAgente);

			try {

				descriptions = AMSService.search(myAgent, amsAgentDescription);

				logger.info("Inviato messaggio find agent "+descriptions);

				AID aid = GetAID.aid(nomeAgente);
				int i = 0;
				while(i<descriptions.length && !descriptions[i].getName().equals(aid))
					i++;

				if(i<descriptions.length)
				{
					step=4;
					logger.info("Agente Esiste");
				}
				else{
					step=1;
					logger.info("Agente Non Esiste");
				}				

//				logger.info("description lenght: "+descriptions.length);
//
//				for( AMSAgentDescription ams : descriptions ){
//					logger.info("XXXXXX --> "+ams.toString());
//				}
//
//
//
//
//				if(descriptions.length==0)
//				{
//					step=1;
//					logger.info("Agente Non Esiste");
//				}
//				else {
//					step=4;
//					logger.info("Agente Esiste");
//				}

			} catch (FIPAException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();


				logger.info("ERRORE NEL COMUNICARE CON AMS");
				step = 4;
			}



			break;
		}
		case 1:
		{
			logger.info("STEP 1");

			if(descriptions.length == 0) {

				AID amsServerAid = myAgent.getAMS();

				ContainerID containerID = new ContainerID();
				containerID.setMain(true);
				containerID.setName("Main-Container");		

				CreateAgent createAgent = new CreateAgent();
				createAgent.setAgentName(myAgent.getLocalName().replace("$mobile", ""));  					//Sostituisco @ con # nel nome dell' agente 
				createAgent.setClassName("agend.agents.AgendAgent");

				String [] credenziali = new String[] {myAgent.getLocalName().replace("#", "@").replace("$mobile", ""), password, myAgent.getLocalName()};				//Mentre le credenziali per l' accesso a google rimangono le stesse
				createAgent.addArguments(credenziali);
				createAgent.setContainer(containerID);

				Action action = new Action();
				action.setActor(amsServerAid);
				action.setAction(createAgent);

				ACLMessage amsRequest = new ACLMessage(ACLMessage.REQUEST);
				amsRequest.setSender(myAgent.getAID());
				amsRequest.addReceiver(amsServerAid);
				amsRequest.setLanguage(FIPANames.ContentLanguage.FIPA_SL0);
				amsRequest.setOntology(JADEManagementOntology.NAME);
				amsRequest.setProtocol(FIPANames.InteractionProtocol.FIPA_REQUEST);

				messageTemplate = MessageTemplate.and(MessageTemplate.MatchSender(GetAID.aid(myAgent.getLocalName().replace("$mobile", ""))), MessageTemplate.MatchConversationId("Credential"));

				try {

					myAgent.getContentManager().registerLanguage(SLCodec.class.newInstance(), "fipa-sl0");
					myAgent.getContentManager().registerOntology(JADEManagementOntology.getInstance());
					myAgent.getContentManager().fillContent(amsRequest, action);

					myAgent.send(amsRequest);			

					step = 2;

				} catch (InstantiationException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					step = 4;
				} catch (IllegalAccessException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					step = 4;
				} catch (CodecException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					step = 4;
				} catch (OntologyException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					step = 4;
				}
			}
			else
			{
				step = 3;
			}

			break;
		}
		case 2:
		{
			ACLMessage message = myAgent.receive(messageTemplate);
			logger.info("STEP 2");

			if(message!=null) {

				if( message.getPerformative() == ACLMessage.FAILURE )
				{

					logger.info("FAILURE: KILL AGENT");

					AID amsServerAid = myAgent.getAMS();

					ContainerID containerID = new ContainerID();
					containerID.setMain(true);
					containerID.setName("Main-Container");		

					KillAgent killAgent = new KillAgent();
					killAgent.setAgent(GetAID.aid(myAgent.getLocalName().replace("$mobile", "")));

					Action action = new Action();
					action.setActor(amsServerAid);
					action.setAction(killAgent);

					ACLMessage amsRequest = new ACLMessage(ACLMessage.REQUEST);
					amsRequest.setSender(myAgent.getAID());
					amsRequest.addReceiver(amsServerAid);
					amsRequest.setLanguage(FIPANames.ContentLanguage.FIPA_SL0);
					amsRequest.setOntology(JADEManagementOntology.NAME);
					amsRequest.setProtocol(FIPANames.InteractionProtocol.FIPA_REQUEST);

					try {

						myAgent.getContentManager().registerLanguage(SLCodec.class.newInstance(), "fipa-sl0");
						myAgent.getContentManager().registerOntology(JADEManagementOntology.getInstance());
						myAgent.getContentManager().fillContent(amsRequest, action);

						myAgent.send(amsRequest);			

					} catch (InstantiationException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
						step = 4;
					} catch (IllegalAccessException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
						step = 4;
					} catch (CodecException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
						step = 4;
					} catch (OntologyException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
						step = 4;
					}

					System.out.println("AGENTE CANCELLATO!!!!");

					step = 4;
				}
				else if( message.getPerformative() == ACLMessage.CONFIRM )
				{
					logger.info("MESSAGGIO RICEVUTO INFORM");

					AID aid = GetAID.registration();

					ACLMessage aclMessage = new ACLMessage(ACLMessage.INFORM);
					aclMessage.setSender(myAgent.getAID());
					aclMessage.addReceiver(aid);
					aclMessage.setContent(myAgent.getLocalName().replace("#", "@").replace("$mobile", "")+"-"+password);

					myAgent.send(aclMessage);

					step = 3;
				}
			}
			else
				block();

			break;
		}
		case 3:
		{
			logger.info("STEP 3");

			activity.switchActivity();

			step = 4;

			break;
		}
		default:
			break;
		}
	}

	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}

	@Override
	public boolean done() {

		return (step == 4);
	}

}
